#!/bin/bash
#
# This script registers the identities for the three organizations.

source ./utils.sh

# Returns 1 if the directory for the CA client exists.
checkExistence() {
    if [ -d ${FABRIC_CA_CLIENT_HOME} ]; then
        printf "The client directory for '%s' seems to already exists. Delete it first if you'd like to perform the operations for this organization again.\n" $ORG_NAME

        return 1
    fi
}

# Enrolls the CA admin to fetch the cert files for it.
enrollCaAdmin() {
    printf "Enrolling as the admin of '${ORG_NAME}'..."

    fabric-ca-client enroll -u https://admin:adminpw@localhost:${FABRIC_CA_SERVER_PORT} --caname ${FABRIC_CA_SERVER_CA_NAME} --tls.certfiles ${WORKING_DIR}/server/${ORG_NAME}/tls-cert.pem >/dev/null 2>&1

    if [ $? -ne 0 ]; then
        printf "\rError enrolling as the admin of '${ORG_NAME}'.\n"
    else
        printf "\rEnrolled as the admin of '${ORG_NAME}'.\n"
    fi
}

# Registers an identity on behalf of the organization admin.
registerIdentity() {
    local IS_ID_ATTRS_NEEDED=false
    if [ $# -ge 4 ]; then
        IS_ID_ATTRS_NEEDED=true
    fi

    local readonly ID_NAME=$1
    shift
    local readonly ID_SECRET=$1
    shift
    local readonly ID_TYPE=$1
    shift
    if [ ${IS_ID_ATTRS_NEEDED} == true ]; then
        local readonly ID_ATTRS=$1
        shift
    fi
    
    if [ ${IS_ID_ATTRS_NEEDED} == true ]; then
        fabric-ca-client register --caname ${FABRIC_CA_SERVER_CA_NAME} --id.name ${ID_NAME} --id.secret ${ID_SECRET} --id.type ${ID_TYPE} --id.attrs ${ID_ATTRS} --tls.certfiles ${WORKING_DIR}/server/${ORG_NAME}/tls-cert.pem >/dev/null 2>&1
    else
        fabric-ca-client register --caname ${FABRIC_CA_SERVER_CA_NAME} --id.name ${ID_NAME} --id.secret ${ID_SECRET} --id.type ${ID_TYPE} --tls.certfiles ${WORKING_DIR}/server/${ORG_NAME}/tls-cert.pem >/dev/null 2>&1
    fi

    return $?
}

# This is a helper function that wraps `registerIdentity()` with text responses.
registerIdentityWithTextResponse() {
    local readonly IDENTITY_DISPLAY_NAME=$1
    shift
    local readonly ID_NAME=$1
    shift
    local readonly ID_SECRET=$1
    shift
    local readonly ID_TYPE=$1
    shift
    local readonly ID_ATTRS=$1
    shift

    printf "Registering '${IDENTITY_DISPLAY_NAME}'..."
    registerIdentity ${ID_NAME} ${ID_SECRET} ${ID_TYPE} ${ID_ATTRS}
    local RET_VAL=$?
    if [ $? -ne 0 ]; then
        printf "\rError registering '${IDENTITY_DISPLAY_NAME}'.\n"
        return RET_VAL
    else
        printf "\rDone registering '${IDENTITY_DISPLAY_NAME}'.\n"
    fi
}

# Registers all the identities of the organization indicated by `$ORG_NAME`.
registerIdentities() {
    declare -i local RET_VAL=0

    if [ ${ORG_NAME} == "ordererOrg" ]; then
        registerIdentityWithTextResponse "orderer.lab805.com" "orderer" "ordererpw" "orderer"
        registerIdentityWithTextResponse "orderer2.lab805.com" "orderer2" "orderer2pw" "orderer"
        registerIdentityWithTextResponse "Admin@lab805.com" "ordererAdmin" "ordererAdminpw" "admin"
    else
        registerIdentityWithTextResponse "peer0.${ORG_NAME}.lab805.com" "peer0" "peer0pw" "peer" '"hf.Registrar.Roles=peer"'
        RET_VAL+=$?
        registerIdentityWithTextResponse "peer1.${ORG_NAME}.lab805.com" "peer1" "peer1pw" "peer" '"hf.Registrar.Roles=peer"'
        RET_VAL+=$?
        registerIdentityWithTextResponse "User1@${ORG_NAME}.lab805.com" "user1" "user1pw" "client" '"hf.Registrar.Roles=client"'
        RET_VAL+=$?
        registerIdentityWithTextResponse "Admin@${ORG_NAME}.lab805.com" "${ORG_NAME}admin" "${ORG_NAME}adminpw" "admin" '"hf.Registrar.Roles=admin"'
        RET_VAL+=$?
    fi
}

# Creates a config file that enables node OUs for the organization indicated by `$ORG_NAME`.
createNodeOuConfigFile() {
    echo "NodeOUs:
  Enable: true
  ClientOUIdentifier:
    Certificate: cacerts/localhost-${FABRIC_CA_SERVER_PORT}-${FABRIC_CA_SERVER_CA_NAME}.pem
    OrganizationalUnitIdentifier: client
  PeerOUIdentifier:
    Certificate: cacerts/localhost-${FABRIC_CA_SERVER_PORT}-${FABRIC_CA_SERVER_CA_NAME}.pem
    OrganizationalUnitIdentifier: peer
  AdminOUIdentifier:
    Certificate: cacerts/localhost-${FABRIC_CA_SERVER_PORT}-${FABRIC_CA_SERVER_CA_NAME}.pem
    OrganizationalUnitIdentifier: admin
  OrdererOUIdentifier:
    Certificate: cacerts/localhost-${FABRIC_CA_SERVER_PORT}-${FABRIC_CA_SERVER_CA_NAME}.pem
    OrganizationalUnitIdentifier: orderer" >"${FABRIC_CA_CLIENT_HOME}/msp/config.yaml"
}

# Main script
checkBinAvailability || {
    printf "Error: Fabric CA binaries not available.\n"
    exit 1
}

WORKING_DIR=${PWD}

IS_ALL_SUCCESS=true
for ORG_NAME in "org1" "org2" "ordererOrg"; do
    setServerEnvVars
    setClientHome

    # Skip the org if the directory already exists
    checkExistence || {
        IS_ALL_SUCCESS=false
        continue
    }

    # Skip the org if there's error enrolling the admin
    enrollCaAdmin || {
        IS_ALL_SUCCESS=false
        continue
    }

    createNodeOuConfigFile

    registerIdentities || {
        IS_ALL_SUCCESS=false
    }
done

if [ ${IS_ALL_SUCCESS} == false ]; then
    exit 2
fi
